package com.sakura.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sakura.constant.StatusConstant;
import com.sakura.dbo.ForHelpDTO;
import com.sakura.dto.QueryHelpRequestDTO;
import com.sakura.entity.Elderly;
import com.sakura.entity.HelpRequest;
import com.sakura.entity.Manager;
import com.sakura.service.ElderlyService;
import com.sakura.service.HelpRequestService;
import com.sakura.mapper.HelpRequestMapper;
import com.sakura.service.ManagerService;
import com.sakura.socket.controller.WebSocketServer;
import com.sakura.util.EntityConverter;
import com.sakura.util.R;
import com.sakura.vo.HelpPageVO;
import com.sakura.vo.HelpRequestDTO;
import com.sakura.vo.HelpRequestVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.websocket.EncodeException;
import javax.websocket.Session;
import java.io.IOException;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author Sakura
 * @description 针对表【help_request】的数据库操作Service实现
 * @createDate 2023-11-22 15:49:03
 */
@Service
public class HelpRequestServiceImpl extends ServiceImpl<HelpRequestMapper, HelpRequest>
        implements HelpRequestService {
    @Autowired
    private ElderlyService elderlyService;

    @Autowired
    private ManagerService managerService;

    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 老人求助方法
     *
     * @param forHelpDTO:
     * @return void
     * @author Sakura
     * @date 2023/11/24 21:20
     */
    @Override
    public String forHelp(ForHelpDTO forHelpDTO) {
        //1、首先根据电话获取老人的详细信息
        Elderly elderly = elderlyService.getElderlyByPhone(forHelpDTO.getPhone());
//        Elderly elderly = elderlyService.getById(forHelpDTO.getElderlyId());

        //1、先保存数据库
        HelpRequest helpRequest = EntityConverter.copyAndGetSingle(forHelpDTO, HelpRequest.class);
        //根据房间号查询谁负责老人，这里我默认是管理员1
        helpRequest.setGridId(1l);
        helpRequest.setStatus(0);
        helpRequest.setTime(new Date());
        helpRequest.setElderlyId(elderly.getId());
        boolean save = this.save(helpRequest);
        if (!save) {
            return "求助失败，请重新尝试";
        }
        //2、发送消息，查看老人对应的负责人，或者给所有的人喝管理员发送消息,这里直接向所有管理员发送消息吧
        //定义消息体
        Map<String, Object> message = new HashMap<>();
        message.put("elderlyId", elderly.getId());
        message.put("elderlyName", elderly.getName());
        //将求助信息发送给所有管理员
        WebSocketServer.sendToAllClient(message);
        return "请求成功，请原地等待救援";
    }

    /**
     * 根据id查出事件详情
     *
     * @param id:
     * @return HelpRequestDTO
     * @author Sakura
     * @date 2023/11/27 11:14
     */
    @Override
    public HelpRequestDTO getRequestEventById(Long id) {
        HelpRequest helpRequest = this.getById(id);
        //查出负责的网格员
        Manager manager = managerService.getById(helpRequest.getGridId());

        Elderly elderly = elderlyService.getById(helpRequest.getElderlyId());

        //封装视图
        HelpRequestDTO helpRequestDTO = EntityConverter.copyAndGetSingle(helpRequest, HelpRequestDTO.class);
        helpRequestDTO.setElderlyId(elderly.getId())
                .setElderlyName(elderly.getName())
                .setElderlyPhone(elderly.getPhone())
                .setGridId(manager.getId())
                .setGridName(manager.getName())
                .setGridPhone(manager.getPhone());
        return helpRequestDTO;
    }

    @Override
    public Map<String, Object> getListByElderlyId(Long elderlyId) {
        //返回结果对象
        Map<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<HelpRequest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HelpRequest::getElderlyId, elderlyId);
        List<HelpRequest> helpRequestsList = this.list(queryWrapper);
        AtomicInteger unDisposeNum = new AtomicInteger();
        AtomicInteger disposingNum = new AtomicInteger();
        AtomicInteger disposedNum = new AtomicInteger();

        List<HelpRequestVO> requestVOList = helpRequestsList.stream().map(item -> {
            HelpRequestVO helpRequestVO = EntityConverter.copyAndGetSingle(item, HelpRequestVO.class);
            if (item.getGridId() != null) {
                Manager manager = managerService.getById(item.getGridId());
                helpRequestVO.setGridName(manager.getName());
                helpRequestVO.setGridPhone(manager.getPhone());
            }
            if (item.getStatus() != null) {
                if (item.getStatus() == StatusConstant.UN_DISPOSE) {
                    unDisposeNum.getAndIncrement();

                } else if (item.getStatus() == StatusConstant.DISPOSE_ING) {
                    disposingNum.getAndIncrement();

                } else if (item.getStatus() == StatusConstant.DISPOSE_ED) {
                    disposedNum.getAndIncrement();
                }
            }
            return helpRequestVO;
        }).collect(Collectors.toList());
        map.put("list", requestVOList);
        map.put("unDisposeNum", unDisposeNum.get());
        map.put("disposingNum", disposingNum.get());
        map.put("disposedNum", disposedNum.get());
        return map;
    }

    @Override
    public R getList(QueryHelpRequestDTO queryHelpRequestDTO) {
        //管理员姓名不为空的形况下，先去查看管理员的过滤条件
        List<Long> gridIdList = new ArrayList<>();
        if (queryHelpRequestDTO.getGridName() != null && !"".equals(queryHelpRequestDTO.getGridName())) {
            LambdaQueryWrapper<Manager> gridWrapper = new LambdaQueryWrapper<>();
            gridWrapper.like(Manager::getName, queryHelpRequestDTO.getGridName());
            List<Manager> managerList = managerService.list(gridWrapper);
            gridIdList = managerList.stream().map(item -> item.getId()).collect(Collectors.toList());
        }
        //老人不为空的情况下，对老人的查询条件进行过滤
        List<Long> elderlyIdList = new ArrayList<>();
        if (queryHelpRequestDTO.getElderlyName() != null && !"".equals(queryHelpRequestDTO.getElderlyName())) {
            LambdaQueryWrapper<Elderly> elderlyWrapper = new LambdaQueryWrapper<>();
            elderlyWrapper.like(Elderly::getName, queryHelpRequestDTO.getElderlyName());
            List<Elderly> elderlyList = elderlyService.list(elderlyWrapper);
            elderlyIdList = elderlyList.stream().map(item -> item.getId()).collect(Collectors.toList());
        }
        LambdaQueryWrapper<HelpRequest> queryWrapper = new LambdaQueryWrapper<>();
        if (queryHelpRequestDTO.getId() != null && queryHelpRequestDTO.getId() != 0) {
            queryWrapper.eq(HelpRequest::getId, queryHelpRequestDTO.getId());
        }
        if (queryHelpRequestDTO.getStatus() != null) {
            queryWrapper.eq(HelpRequest::getStatus, queryHelpRequestDTO.getStatus());
        }

        if (gridIdList.size() > 0) {
            queryWrapper.in(HelpRequest::getGridId, gridIdList);
        }
        if (elderlyIdList.size() > 0) {
            queryWrapper.in(HelpRequest::getElderlyId, elderlyIdList);
        }

        Page<HelpRequest> helpRequestPage =
                this.page(new Page<>(queryHelpRequestDTO.getCurrent(), queryHelpRequestDTO.getPageSize()), queryWrapper);
        List<HelpPageVO> voList = helpRequestPage.getRecords().stream().map(item -> {
            HelpPageVO pageHelpVO = EntityConverter.copyAndGetSingle(item, HelpPageVO.class);
            if (item.getGridId() != null) {
                Manager manager = managerService.getById(item.getGridId());
                pageHelpVO.setGridName(manager.getName());
                pageHelpVO.setGridPhone(manager.getPhone());
            }

            if (item.getElderlyId() != null) {
                Elderly elderly = elderlyService.getById(item.getElderlyId());
                pageHelpVO.setElderlyName(elderly.getName());
            }
            return pageHelpVO;
        }).collect(Collectors.toList());
        Page<HelpPageVO> helpPageVOPage = new Page<>();
        BeanUtils.copyProperties(helpRequestPage, helpPageVOPage, "records");
        helpPageVOPage.setRecords(voList);
        return R.success(helpPageVOPage);
    }

    /**
     * 这里是错误代码，请核对改正
     * @param id:
     * @return R
     * @author Sakura
     * @date 2024/1/2 14:44
     */
//    @Override
//    public R getList(QueryHelpRequestDTO queryHelpRequestDTO) {
//        //管理员姓名不为空的形况下，先去查看管理员的过滤条件
//        List<Long> gridIdList = new ArrayList<>();
//        if (queryHelpRequestDTO.getGridName() != null&&!"".equals(queryHelpRequestDTO.getGridName())) {
//            LambdaQueryWrapper<Manager> gridWrapper = new LambdaQueryWrapper<>();
//            gridWrapper.like(Manager::getName, queryHelpRequestDTO.getGridName());
//            List<Manager> managerList = managerService.list(gridWrapper);
//            gridIdList = managerList.stream().map(item -> item.getId()).collect(Collectors.toList());
//        }
//        //老人不为空的情况下，对老人的查询条件进行过滤
//        List<Long> elderlyIdList = new ArrayList<>();
//        if (queryHelpRequestDTO.getElderlyName()!= null&&!"".equals(queryHelpRequestDTO.getElderlyName())) {
//            LambdaQueryWrapper<Elderly> elderlyWrapper = new LambdaQueryWrapper<>();
//            elderlyWrapper.like(Elderly::getName, queryHelpRequestDTO.getElderlyName());
//            List<Elderly> elderlyList = elderlyService.list(elderlyWrapper);
//           elderlyIdList = elderlyList.stream().map(item -> item.getId()).collect(Collectors.toList());
//        }
//        LambdaQueryWrapper<HelpRequest> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper
//                .eq(queryHelpRequestDTO.getId() != null && queryHelpRequestDTO.getId() != 0, HelpRequest::getId, queryHelpRequestDTO.getId())
//                .eq(HelpRequest::getStatus, queryHelpRequestDTO.getStatus())
//                .in(gridIdList.size() > 0, HelpRequest::getGridId, gridIdList)
//                .in(elderlyIdList.size() > 0, HelpRequest::getElderlyId, elderlyIdList);
//        Page<HelpRequest> helpRequestPage = this.page(new Page<>(queryHelpRequestDTO.getCurrent(), queryHelpRequestDTO.getPageSize()), queryWrapper);
//
//        //接下来处理结果
//        List<HelpPageVO> list = helpRequestPage.getRecords().stream().map(item -> {
//            HelpPageVO pageHelpVO = EntityConverter.copyAndGetSingle(item, HelpPageVO.class);
//            if (item.getGridId() != null) {
//                Manager manager = managerService.getById(item.getGridId());
//                pageHelpVO.setGridName(manager.getName());
//            }
//            return pageHelpVO;
//        }).collect(Collectors.toList());
//        return R.success(list);
//    }

    /**
     * 根据id提醒网格员该处理消息了
     * @param id:
     * @return R
     * @author Sakura
     * @date 2024/1/2 14:44
     */
    @Override
    public R handleForHelp(Long id) {
        HelpRequest helpRequest = this.getById(id);
        Session myGridSession = webSocketServer.getMyGridSession(helpRequest.getGridId()+"");
        if (myGridSession!= null) {
            try {
                Map<String, Object> message = new HashMap<>();
                message.put("id", id);
                message.put("time", LocalTime.now());
                HelpRequestDTO helpRequestDTO = EntityConverter.copyAndGetSingle(helpRequest, HelpRequestDTO.class);
                message.put("event", helpRequestDTO);
                myGridSession.getBasicRemote().sendObject(message);
                return R.success();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (EncodeException e) {
                e.printStackTrace();
            }
        }
        return R.error("管理员不在线，请电话联系");
    }

}




